// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using NUnit.Framework;
using ValidationAspects.Exceptions;
using ValidationAspects.Factories;

namespace TestValidationAspects.Factories
{
	[TestFixture]
	public class TestMaximum
	{
		private static void Fail<T>(double value, T actual)
		{
			Test.Throws<ValidateMaximumException>(() => new Maximum {Value = value}.Create<T>().Invoke(actual, new MockValidationContext()), new ValidateMaximumException(value, actual).Message);
		}

		private static void Pass<T>(double value, T actual)
		{
			new Maximum {Value = value}.Create<T>().Invoke(actual, new MockValidationContext());
		}

		[Test]
		[ExpectedException(typeof(UnsupportedValidationException))]
		public void Test_CreateValidator_throws_for_unsupported_type()
		{
			new Maximum().Create<string>();
		}

		[Test]
		public void Test_Maximum_double()
		{
			Pass<double>(1, 0);
			Pass<double>(1, 1);
			Fail<double>(1, 2);
		}

		[Test]
		public void Test_Maximum_decimal()
		{
			Pass<decimal>(1, 0);
			Pass<decimal>(1, 1);
			Fail<decimal>(1, 2);
		}

		[Test]
		public void Test_Maximum_int()
		{
			Pass(1, 0);
			Pass(1, 1);
			Fail(1, 2);
		}

		[Test]
		public void Test_Maximum_long()
		{
			Pass<long>(1, 0);
			Pass<long>(1, 1);
			Fail<long>(1, 2);
		}

		[Test]
		public void Test_Maximum_float()
		{
			Pass<float>(1, 0);
			Pass<float>(1, 1);
			Fail<float>(1, 2);
		}

		[Test]
		public void Test_Maximum_short()
		{
			Pass<short>(1, 0);
			Pass<short>(1, 1);
			Fail<short>(1, 2);
		}

		[Test]
		public void Test_Maximum_char()
		{
			Pass('1', '0');
			Pass('1', '1');
			Fail('1', '2');
		}

		[Test]
		public void Test_Maximum_byte()
		{
			Pass<byte>(1, 0);
			Pass<byte>(1, 1);
			Fail<byte>(1, 2);
		}

		[Test]
		public void Test_Maximum_uint()
		{
			Pass<uint>(1, 0);
			Pass<uint>(1, 1);
			Fail<uint>(1, 2);
		}

		[Test]
		public void Test_Maximum_ulong()
		{
			Pass<ulong>(1, 0);
			Pass<ulong>(1, 1);
			Fail<ulong>(1, 2);
		}

		[Test]
		public void Test_Maximum_ushort()
		{
			Pass<ushort>(1, 0);
			Pass<ushort>(1, 1);
			Fail<ushort>(1, 2);
		}

		[Test]
		public void Test_Maximum_sbyte()
		{
			Pass<sbyte>(1, 0);
			Pass<sbyte>(1, 1);
			Fail<sbyte>(1, 2);
		}


		[Test]
		public void Test_Maximum_Nullable_double()
		{
			Pass<double?>(1, 0);
			Pass<double?>(1, 1);
			Fail<double?>(1, 2);

			Pass<double?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_decimal()
		{
			Pass<decimal?>(1, 0);
			Pass<decimal?>(1, 1);
			Fail<decimal?>(1, 2);

			Pass<decimal?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_int()
		{
			Pass<int?>(1, 0);
			Pass<int?>(1, 1);
			Fail<int?>(1, 2);

			Pass<int?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_long()
		{
			Pass<long?>(1, 0);
			Pass<long?>(1, 1);
			Fail<long?>(1, 2);

			Pass<long?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_float()
		{
			Pass<float?>(1, 0);
			Pass<float?>(1, 1);
			Fail<float?>(1, 2);

			Pass<float?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_short()
		{
			Pass<short?>(1, 0);
			Pass<short?>(1, 1);
			Fail<short?>(1, 2);

			Pass<short?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_char()
		{
			Pass<char?>('1', '0');
			Pass<char?>('1', '1');
			Fail<char?>('1', '2');

			Pass<char?>('1', null);
		}

		[Test]
		public void Test_Maximum_Nullable_byte()
		{
			Pass<byte?>(1, 0);
			Pass<byte?>(1, 1);
			Fail<byte?>(1, 2);

			Pass<byte?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_uint()
		{
			Pass<uint?>(1, 0);
			Pass<uint?>(1, 1);
			Fail<uint?>(1, 2);

			Pass<uint?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_ulong()
		{
			Pass<ulong?>(1, 0);
			Pass<ulong?>(1, 1);
			Fail<ulong?>(1, 2);

			Pass<ulong?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_ushort()
		{
			Pass<ushort?>(1, 0);
			Pass<ushort?>(1, 1);
			Fail<ushort?>(1, 2);

			Pass<ushort?>(1, null);
		}

		[Test]
		public void Test_Maximum_Nullable_sbyte()
		{
			Pass<sbyte?>(1, 0);
			Pass<sbyte?>(1, 1);
			Fail<sbyte?>(1, 2);

			Pass<sbyte?>(1, null);
		}
	}
}